package com.android.systemui.statusbar.board;

import android.content.ContentResolver;
import android.content.Context;
import android.net.LinkAddress;
import android.net.ProxyInfo;
import android.net.wifi.WifiManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.regex.Pattern;

/**
 * Class  Name: EthernetUtil
 * Description:
 * Created by bruce on 17/8/26
 */
public class EthernetUtil {

    private static String TAG = EthernetUtil.class.getSimpleName();

    public static final String ETHERNET_USE_STATIC_IP = "ethernet_use_static_ip";

    public static final String ETHERNET_STATE_CHANGED_ACTION = "android.net.ethernet.ETHERNET_STATE_CHANGED";
    public static final String EXTRA_ETHERNET_STATE = "ethernet_state";

    public static final int ETHER_STATE_DISCONNECTED = 0;
    public static final int ETHER_STATE_CONNECTING = 1;
    public static final int ETHER_STATE_CONNECTED = 2;

    public static final String ETHERNET_STATIC_IP = "ethernet_static_ip";
    public static final String ETHERNET_STATIC_GATEWAY = "ethernet_static_gateway";
    public static final String ETHERNET_STATIC_NETMASK = "ethernet_static_netmask";
    public static final String ETHERNET_STATIC_DNS1 = "ethernet_static_dns1";
    public static final String ETHERNET_STATIC_DNS2 = "ethernet_static_dns2";

    Context mContext;
    ContentResolver contentResolver;
    public HashMap<Object, Object> ipAssignmentMap;

    public EthernetUtil(Context mContext) {
        this.mContext = mContext;
        contentResolver = this.mContext.getContentResolver();
    }

    public void init() {
        try {
            //获取ETHERNET_SERVICE参数
            String ETHERNET_SERVICE = (String) Context.class.getField("ETHERNET_SERVICE").get(null);
            Class<?> ethernetManagerClass = Class.forName("android.net.EthernetManager");
            Class<?> ipConfigurationClass = Class.forName("android.net.IpConfiguration");

            //获取ethernetManager服务对象
            Object ethernetManager = mContext.getSystemService(ETHERNET_SERVICE);
            Object getConfiguration = ethernetManagerClass
                    .getDeclaredMethod("getConfiguration").invoke(ethernetManager);

            Log.e(TAG, "ETHERNET_SERVICE : " + ETHERNET_SERVICE);

            //获取在EthernetManager中的抽象类mService成员变量
            Field mService = ethernetManagerClass.getDeclaredField("mService");
            //修改private权限
            mService.setAccessible(true);
            //获取抽象类的实例化对象
            Object mServiceObject = mService.get(ethernetManager);

            Class<?> iEthernetManagerClass = Class.forName("android.net.IEthernetManager");

            Method[] methods = iEthernetManagerClass.getDeclaredMethods();

            for (Method ms : methods) {
                if (ms.getName().equals("setEthernetEnabled")) {
                    ms.invoke(mServiceObject, true);
                    Log.e(TAG, "mServiceObject : " + mServiceObject);
                }

            }
            Class<?> staticIpConfig = Class.forName("android.net.StaticIpConfiguration");

            Constructor<?> staticIpConfigConstructor = staticIpConfig.getDeclaredConstructor(staticIpConfig);

            Object staticIpConfigInstance = staticIpConfig.newInstance();

            //获取LinkAddress里面只有一个String类型的构造方法
            Constructor<?> linkAddressConstructor = LinkAddress.class.getDeclaredConstructor(String.class);

            //实例化带String类型的构造方法
            LinkAddress linkAddress = (LinkAddress) linkAddressConstructor.newInstance("192.168.1.10/24");
            //192.168.1.1/24--子网掩码长度,24相当于255.255.255.0

            Class<?> inetAddressClass = Class.forName("java.net.InetAddress");

            //默认网关参数
            byte[] bytes = new byte[]{(byte) 192, (byte) 168, 3, 1};

            Constructor<?>[] inetAddressConstructors = inetAddressClass.getDeclaredConstructors();

            for (Constructor inetc : inetAddressConstructors) {

                //获取有三种参数类型的构造方法
                if (inetc.getParameterTypes().length == 3) {
                    //修改权限
                    inetc.setAccessible(true);

                    WifiManager wm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);

                    int ipAddressInt = wm.getConnectionInfo().getIpAddress();

                    //hostName主机名
                    String hostName = String.format(Locale.getDefault(), "%d.%d.%d.%d",
                            (ipAddressInt & 0xff), (ipAddressInt >> 8 & 0xff),
                            (ipAddressInt >> 16 & 0xff), (ipAddressInt >> 24 & 0xff));
//                    InetAddress inetAddress = (InetAddress) inetc.newInstance(2, bytes, hostName);
                }

            }
            //获取staticIpConfig中所有的成员变量
            Field[] declaredFields = staticIpConfigInstance.getClass().getDeclaredFields();

            for (Field f : declaredFields) {
                //设置成员变量的值
                if (f.getName().equals("ipAddress")) {
                    //设置IP地址和子网掩码
                    f.set(staticIpConfigInstance, linkAddress);
                } else if (f.getName().equals("gateway")) {
                    //设置默认网关
//                    f.set(staticIpConfigInstance, inetAddress);
                } else if (f.getName().equals("domains")) {
                    f.set(staticIpConfigInstance, "");
                }/*else if (f.getName().equals("dnsServers")){

               //设置DNS
                    f.set(staticIpConfigInstance,new ArrayList<InetAddress>());
                }*/

            }
            Object staticInstance = staticIpConfigConstructor.newInstance(staticIpConfigInstance);

            //存放ipASSignment枚举类参数的集合
            ipAssignmentMap = new HashMap();

            //存放proxySettings枚举类参数的集合
            HashMap proxySettingsMap = new HashMap();

            Class<?>[] enumClass = ipConfigurationClass.getDeclaredClasses();

            for (Class enumC : enumClass) {
                //获取枚举数组
                Object[] enumConstants = enumC.getEnumConstants();

                if (enumC.getSimpleName().equals("ProxySettings")) {
                    for (Object enu : enumConstants) {
                        //设置代理设置集合 STATIC DHCP UNASSIGNED PAC
                        proxySettingsMap.put(enu.toString(), enu);
                    }
                } else if (enumC.getSimpleName().equals("IpAssignment")) {
                    for (Object enu : enumConstants) {
                        //设置以太网连接模式设置集合 STATIC DHCP UNASSIGNED
                        ipAssignmentMap.put(enu.toString(), enu);
                    }
                }
            }
            //获取ipConfiguration类的构造方法
            Constructor<?>[] ipConfigConstructors = ipConfigurationClass.getDeclaredConstructors();
            Object ipConfigurationInstance = null;
            for (Constructor constru : ipConfigConstructors) {

                //获取ipConfiguration类的4个参数的构造方法
                if (constru.getParameterTypes().length == 4) {//设置以上四种类型

                    //初始化ipConfiguration对象,设置参数
                    ipConfigurationInstance = constru.newInstance(ipAssignmentMap.get("STATIC"),
                            proxySettingsMap.get("NONE"), staticInstance, ProxyInfo.buildDirectProxy(null, 0));
                }
            }

            //获取ipConfiguration类中带有StaticIpConfiguration参数类型的名叫setStaticIpConfiguration的方法
            Method setStaticIpConfiguration = ipConfigurationClass
                    .getDeclaredMethod("setStaticIpConfiguration", staticIpConfig);

            //修改private方法权限
            setStaticIpConfiguration.setAccessible(true);

            //在ipConfiguration对象中使用setStaticIpConfiguration方法,并传入参数
            setStaticIpConfiguration.invoke(ipConfigurationInstance, staticInstance);

            Object ethernetManagerInstance = ethernetManagerClass.getDeclaredConstructor(Context.class,
                    iEthernetManagerClass).newInstance(ethernetManager, mServiceObject);

            ethernetManagerClass.getDeclaredMethod("setConfiguration", ipConfigurationClass)
                    .invoke(ethernetManagerInstance, ipConfigurationInstance);

            Log.e(TAG, "getConfiguration : " + getConfiguration.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String getStaticIp() {
        return Settings.System.getString(contentResolver, ETHERNET_STATIC_IP);
    }

    public String getGateway() {
        return Settings.System.getString(contentResolver, ETHERNET_STATIC_NETMASK);
    }

    public String getNetMask() {
        return Settings.System.getString(contentResolver, ETHERNET_STATIC_GATEWAY);
    }

    public String getDns1() {
        return Settings.System.getString(contentResolver, ETHERNET_STATIC_DNS1);
    }

    public String getDns2() {
        return Settings.System.getString(contentResolver, ETHERNET_STATIC_DNS2);
    }

    public void saveIpSettingInfo(String ip, String netMask,
                                  String gateway, String dns1, String dns2) {
        ContentResolver contentResolver = mContext.getContentResolver();
        if (!TextUtils.isEmpty(ip)) { // not empty
            Settings.System.putString(contentResolver, ETHERNET_STATIC_IP, ip);
        } else {
            Settings.System.putString(contentResolver, ETHERNET_STATIC_IP, null);
        }
        if (!TextUtils.isEmpty(gateway)) { // not empty
            Settings.System.putString(contentResolver, ETHERNET_STATIC_GATEWAY, gateway);
        } else {
            Settings.System.putString(contentResolver, ETHERNET_STATIC_GATEWAY, null);
        }
        if (!TextUtils.isEmpty(netMask)) { // not empty
            Settings.System.putString(contentResolver, ETHERNET_STATIC_NETMASK, netMask);
        } else {
            Settings.System.putString(contentResolver, ETHERNET_STATIC_NETMASK, null);
        }
        if (!TextUtils.isEmpty(dns1)) { // not empty
            Settings.System.putString(contentResolver, ETHERNET_STATIC_DNS1, dns1);
        } else {
            Settings.System.putString(contentResolver, ETHERNET_STATIC_DNS1, null);
        }
        if (!TextUtils.isEmpty(dns2)) { // not empty
            Settings.System.putString(contentResolver, ETHERNET_STATIC_DNS2, dns2);
        } else {
            Settings.System.putString(contentResolver, ETHERNET_STATIC_DNS2, null);
        }
    }

    /*
     * 返回 指定的 String 是否是 有效的 IP 地址.
     */
    public boolean isValidIpAddress(String value) {
        int start = 0;
        int end = value.indexOf('.');
        int numBlocks = 0;

        while (start < value.length()) {
            if (-1 == end) {
                end = value.length();
            }

            try {
                int block = Integer.parseInt(value.substring(start, end));
                if ((block > 255) || (block < 0)) {
                    Log.w("EthernetIP",
                            "isValidIpAddress() : invalid 'block', block = " + block);
                    return false;
                }
            } catch (NumberFormatException e) {
                Log.w("EthernetIP", "isValidIpAddress() : e = " + e);
                return false;
            }

            numBlocks++;

            start = end + 1;
            end = value.indexOf('.', start);
        }
        return numBlocks == 4;
    }

    public boolean isValidNetMask(String netMask) {
        Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}" +
                "(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$");
        return pattern.matcher(netMask).matches();
    }

    public boolean checkIPValue(String ip, String netMask, String gateway, String dns1, String dns2) {
        boolean enable = false;
        Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}" +
                "(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$");
        if (isValidIpAddress(ip) && isValidIpAddress(gateway)
                && isValidIpAddress(dns1) && (pattern.matcher(netMask).matches())) {
            if (TextUtils.isEmpty(dns2)) { // 为空可以不考虑
                enable = true;
            } else {
                if (isValidIpAddress(dns2)) {
                    enable = true;
                } else {
                    enable = false;
                }
            }
        } else {
            enable = false;
        }
        return enable;
    }

    public String systemPropertiesGet(String key) {
        String result = "";
        try {
            Class<?> c = Class.forName("android.os.SystemProperties");

            Method get = c.getMethod("get", String.class);

            result = (String) get.invoke(c, key);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 打开DHCP时初始化
     */
    public void setDHCPConfiguration() {
        android.provider.Settings.System.putInt(mContext.getContentResolver(),
                ETHERNET_USE_STATIC_IP, 0);
        try {
            String ETHERNET_SERVICE = (String) Context.class.getField("ETHERNET_SERVICE").get(null);
            Class<?> ethernetManagerClass = Class.forName("android.net.EthernetManager");
            Class<?> ipConfigurationClass = Class.forName("android.net.IpConfiguration");

            //获取ethernetManager服务对象
            Object ethernetManager = mContext.getSystemService(ETHERNET_SERVICE);

            Log.e(TAG, "ETHERNET_SERVICE : " + ETHERNET_SERVICE);
            //获取在EthernetManager中的抽象类mService成员变量
            Field mService = ethernetManagerClass.getDeclaredField("mService");
            //修改private权限
            mService.setAccessible(true);
            //获取抽象类的实例化对象
            Object mServiceObject = mService.get(ethernetManager);

            Class<?> iEthernetManagerClass = Class.forName("android.net.IEthernetManager");

            Method[] methods = iEthernetManagerClass.getDeclaredMethods();


            //存放ipASSignment枚举类参数的集合
            HashMap<Object, Object> ipAssignmentMap = new HashMap();
            //存放proxySettings枚举类参数的集合
            HashMap proxySettingsMap = new HashMap();

            Class<?>[] enumClass = ipConfigurationClass.getDeclaredClasses();

            for (Class enumC : enumClass) {
                //获取枚举数组
                Object[] enumConstants = enumC.getEnumConstants();

                if (enumC.getSimpleName().equals("ProxySettings")) {
                    for (Object enu : enumConstants) {
                        //设置代理设置集合 STATIC DHCP UNASSIGNED PAC
                        proxySettingsMap.put(enu.toString(), enu);
                    }
                } else if (enumC.getSimpleName().equals("IpAssignment")) {
                    for (Object enu : enumConstants) {
                        //设置以太网连接模式设置集合 STATIC DHCP UNASSIGNED
                        ipAssignmentMap.put(enu.toString(), enu);
                    }
                }
            }

            for (Method ms : methods) {
                if (ms.getName().equals("setConfiguration")) {
                    //获取ipConfiguration类的构造方法
                    Constructor<?>[] ipConfigConstructors = ipConfigurationClass.getDeclaredConstructors();
                    Object ipConfigurationInstance = null;
                    for (Constructor constru : ipConfigConstructors) {
                        //获取ipConfiguration类的4个参数的构造方法
                        if (constru.getParameterTypes().length == 4) {//设置以上四种类型
                            //初始化ipConfiguration对象,设置参数
                            ipConfigurationInstance = constru.newInstance(
                                    ipAssignmentMap.get("DHCP"), proxySettingsMap.get("NONE"), null, null);
                        }
                    }
                    ms.invoke(mServiceObject, ipConfigurationInstance);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setStaticConfig(String ipAddress, String netMask, String gateway, String dns1, String dns2) {
        if (!TextUtils.isEmpty(ipAddress)) { // not empty
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_IP, ipAddress);
        } else {
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_IP, null);
        }
        if (!TextUtils.isEmpty(gateway)) { // not empty
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_GATEWAY,
                    gateway);
        } else {
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_GATEWAY,
                    null);
        }
        if (!TextUtils.isEmpty(netMask)) { // not empty
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_NETMASK,
                    netMask);
        } else {
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_NETMASK,
                    null);
        }
        if (!TextUtils.isEmpty(dns1)) { // not empty
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_DNS1, dns1);
        } else {
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_DNS1, null);
        }
        if (!TextUtils.isEmpty(dns2)) { // not empty
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_DNS2, dns2);
        } else {
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_DNS2, null);
        }

        android.provider.Settings.System.putInt(mContext.getContentResolver(),
                ETHERNET_USE_STATIC_IP, 1);
        try {
//            String ETHERNET_SERVICE = (String) Context.class.getField("ETHERNET_SERVICE").get(null);
            Class<?> ethernetManagerClass = Class.forName("android.net.EthernetManager");
            Class<?> ipConfigurationClass = Class.forName("android.net.IpConfiguration");

            //获取ethernetManager服务对象
            Object ethernetManager = mContext.getSystemService("ethernet");

            Log.e(TAG, "ETHERNET_SERVICE : " + "ethernet");
            //获取在EthernetManager中的抽象类mService成员变量
            Field mService = ethernetManagerClass.getDeclaredField("mService");
            //修改private权限
            mService.setAccessible(true);
            //获取抽象类的实例化对象
            Object mServiceObject = mService.get(ethernetManager);

            Class<?> iEthernetManagerClass = Class.forName("android.net.IEthernetManager");

            Method[] methods = iEthernetManagerClass.getDeclaredMethods();


            //存放ipASSignment枚举类参数的集合
            HashMap<Object, Object> ipAssignmentMap = new HashMap();
            //存放proxySettings枚举类参数的集合
            HashMap proxySettingsMap = new HashMap();

            Class<?>[] enumClass = ipConfigurationClass.getDeclaredClasses();

            for (Class enumC : enumClass) {
                //获取枚举数组
                Object[] enumConstants = enumC.getEnumConstants();

                if (enumC.getSimpleName().equals("ProxySettings")) {
                    for (Object enu : enumConstants) {
                        //设置代理设置集合 STATIC DHCP UNASSIGNED PAC
                        proxySettingsMap.put(enu.toString(), enu);
                    }
                } else if (enumC.getSimpleName().equals("IpAssignment")) {
                    for (Object enu : enumConstants) {
                        //设置以太网连接模式设置集合 STATIC DHCP UNASSIGNED
                        ipAssignmentMap.put(enu.toString(), enu);
                    }
                }
            }

            // 获取静态ip配置
            Class<?> staticIpConfig = Class.forName("android.net.StaticIpConfiguration");
            Constructor<?> staticIpConfigConstructor = staticIpConfig.getDeclaredConstructor(staticIpConfig);
            Object staticIpConfigInstance = staticIpConfigConstructor.newInstance();
            //获取staticIpConfig中所有的成员变量
            Inet4Address inetAddr = getIPv4Address(ipAddress);
            int prefixLength = maskStr2InetMask(netMask);
            InetAddress gatewayAddr = getIPv4Address(gateway);
            Field[] declaredFields = staticIpConfigInstance.getClass().getDeclaredFields();
            for (Field f : declaredFields) {
                //设置成员变量的值
                if (f.getName().equals("ipAddress")) {
                    //获取LinkAddress里面只有一个String类型的构造方法

//                    LinkAddress linkAddress = new LinkAddress(inetAddr, prefixLength);

                    Constructor<?> linkAddressConstructor = LinkAddress.class.getDeclaredConstructor(String.class);

                    //实例化带String类型的构造方法
                    LinkAddress linkAddress = (LinkAddress) linkAddressConstructor.newInstance(
                            ipAddress + "/" + prefixLength);
                    f.set(staticIpConfigInstance, linkAddress);

                } else if (f.getName().equals("gateway")) {
                    //设置默认网关
                    f.set(staticIpConfigInstance, gatewayAddr);

                } else if (f.getName().equals("dnsServers")) {
                    ArrayList dnsServers = (ArrayList) f.get(staticIpConfigInstance);
                    if (!TextUtils.isEmpty(dns1)) {
                        try {
                            dnsServers.add(BoardUtil.numericToInetAddress(dns1));
                        } catch (IllegalArgumentException | ClassCastException e) {
                            e.printStackTrace();
                        }
                    }
                    if (!TextUtils.isEmpty(dns2)) {
                        try {
                            dnsServers.add(BoardUtil.numericToInetAddress(dns2));
                        } catch (IllegalArgumentException | ClassCastException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            Object staticInstance = staticIpConfigConstructor.newInstance(staticIpConfigInstance);
            Log.e(TAG, staticInstance.toString());

            for (Method ms : methods) {
                if (ms.getName().equals("setConfiguration")) {
                    //获取ipConfiguration类的构造方法
                    Constructor<?>[] ipConfigConstructors = ipConfigurationClass.getDeclaredConstructors();
                    Object ipConfigurationInstance = null;
                    for (Constructor constru : ipConfigConstructors) {
                        //获取ipConfiguration类的4个参数的构造方法
                        if (constru.getParameterTypes().length == 4) {//设置以上四种类型
                            //初始化ipConfiguration对象,设置参数
                            Log.e(TAG, staticIpConfigInstance.toString());
                            ipConfigurationInstance = constru.newInstance(
                                    ipAssignmentMap.get("STATIC"), proxySettingsMap.get("NONE"),
                                    staticInstance, null);
                        }
                    }
                    ms.invoke(mServiceObject, ipConfigurationInstance);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private Inet4Address getIPv4Address(String text) {
        try {
            return (Inet4Address) BoardUtil.numericToInetAddress(text);
        } catch (Exception e) {
            return null;
        }
    }

    /*
     * convert subMask string to prefix length
     */
    public int maskStr2InetMask(String maskStr) {
        StringBuffer sb;
        String str;
        int inetmask = 0;
        int count = 0;
        /*
         * check the subMask format
    	 */
        Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$");
        if (pattern.matcher(maskStr).matches() == false) {
            Log.e(TAG, "subMask is error");
            return 0;
        }

        String[] ipSegment = maskStr.split("\\.");
        for (int n = 0; n < ipSegment.length; n++) {
            sb = new StringBuffer(Integer.toBinaryString(Integer.parseInt(ipSegment[n])));
            str = sb.reverse().toString();
            count = 0;
            for (int i = 0; i < str.length(); i++) {
                i = str.indexOf("1", i);
                if (i == -1)
                    break;
                count++;
            }
            inetmask += count;
        }
        return inetmask;
    }

    /**
     * 获取以太网连接状态
     *
     * @return
     */
    public int getEthernetConnectState() {
        int state = 0;
        try {
            String ETHERNET_SERVICE = (String) Context.class.getField("ETHERNET_SERVICE").get(null);
            Class<?> ethernetManagerClass = Class.forName("android.net.EthernetManager");

            //获取ethernetManager服务对象
            Object ethernetManager = mContext.getSystemService(ETHERNET_SERVICE);

            Log.e(TAG, "ETHERNET_SERVICE : " + ETHERNET_SERVICE);
            //获取在EthernetManager中的抽象类mService成员变量
            Field mService = ethernetManagerClass.getDeclaredField("mService");
            //修改private权限
            mService.setAccessible(true);
            //获取抽象类的实例化对象
            Object mServiceObject = mService.get(ethernetManager);

            Class<?> iEthernetManagerClass = Class.forName("android.net.IEthernetManager");

            Method[] methods = iEthernetManagerClass.getDeclaredMethods();

            for (Method ms : methods) {
                if (ms.getName().equals("getEthernetConnectState")) {
                    return (int) ms.invoke(mServiceObject);
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return state;
    }

    /**
     * 以太网开关
     *
     * @param enable
     */
    public void setEthernetEnabled(boolean enable) {
        try {
            String ETHERNET_SERVICE = (String) Context.class.getField("ETHERNET_SERVICE").get(null);
            Class<?> ethernetManagerClass = Class.forName("android.net.EthernetManager");

            //获取ethernetManager服务对象
            Object ethernetManager = mContext.getSystemService(ETHERNET_SERVICE);

            Log.e(TAG, "ETHERNET_SERVICE : " + ETHERNET_SERVICE);
            //获取在EthernetManager中的抽象类mService成员变量
            Field mService = ethernetManagerClass.getDeclaredField("mService");
            //修改private权限
            mService.setAccessible(true);
            //获取抽象类的实例化对象
            Object mServiceObject = mService.get(ethernetManager);

            Class<?> iEthernetManagerClass = Class.forName("android.net.IEthernetManager");

            Method[] methods = iEthernetManagerClass.getDeclaredMethods();

            for (Method ms : methods) {
                if (ms.getName().equals("setEthernetEnabled")) {
                    ms.invoke(mServiceObject, enable);
                    Log.e(TAG, "mServiceObject : " + mServiceObject);
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean getEthernetCheckedState() {
        try {
            String ETHERNET_SERVICE = (String) Context.class.getField("ETHERNET_SERVICE").get(null);
            Class<?> ethernetManagerClass = Class.forName("android.net.EthernetManager");

            //获取ethernetManager服务对象
            Object ethernetManager = mContext.getSystemService(ETHERNET_SERVICE);

            Log.e(TAG, "ETHERNET_SERVICE : " + ETHERNET_SERVICE);
            //获取在EthernetManager中的抽象类mService成员变量
            Field mService = ethernetManagerClass.getDeclaredField("mService");
            //修改private权限
            mService.setAccessible(true);
            //获取抽象类的实例化对象
            Object mServiceObject = mService.get(ethernetManager);

            Class<?> iEthernetManagerClass = Class.forName("android.net.IEthernetManager");

            Method[] methods = iEthernetManagerClass.getDeclaredMethods();

            for (Method ms : methods) {
                if (ms.getName().equals("getEthernetIfaceState")) {
                    return (int) ms.invoke(mServiceObject) == 1;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * ip assignment
     *
     * @return
     */
    public String getIpAssignment() {
        String ipAssignment = null;
        try {
            Object mIpAssignment;
            //获取ETHERNET_SERVICE参数
            String ETHERNET_SERVICE = (String) Context.class.getField("ETHERNET_SERVICE").get(null);
            Class<?> ethernetManagerClass = Class.forName("android.net.EthernetManager");

            //获取ethernetManager服务对象
            Object ethernetManager = mContext.getSystemService(ETHERNET_SERVICE);
            Object getConfiguration = ethernetManagerClass
                    .getDeclaredMethod("getConfiguration").invoke(ethernetManager);

            Log.e(TAG, "ETHERNET_SERVICE : " + ETHERNET_SERVICE);


            //######################### Instances of IpAssignment and StaticIpConfiguration #############################

            Field[] filds = getConfiguration.getClass().getDeclaredFields();

            // 获取IpConfiguration
            for (Field f : filds) {
                if (f.getName().equals("ipAssignment")) { // ip assignment
                    Log.d(TAG, "ipAssignment--->" + f.get(getConfiguration));
                    mIpAssignment = f.get(getConfiguration);
                    return mIpAssignment.toString();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ipAssignment;
    }

    public HashMap<String, Object> getEthInfoFromStaticIp() {
        HashMap<String, Object> hashMap = null;
        try {
            //获取ETHERNET_SERVICE参数
            String ETHERNET_SERVICE = (String) Context.class.getField("ETHERNET_SERVICE").get(null);
            Class<?> ethernetManagerClass = Class.forName("android.net.EthernetManager");

            //获取ethernetManager服务对象
            Object ethernetManager = mContext.getSystemService(ETHERNET_SERVICE);
            Object getConfiguration = ethernetManagerClass
                    .getDeclaredMethod("getConfiguration").invoke(ethernetManager);

            Log.e(TAG, "ETHERNET_SERVICE : " + ETHERNET_SERVICE);


            //######################### Instances of StaticIpConfiguration #############################

            Field[] filds = getConfiguration.getClass().getDeclaredFields();

            Object mStaticIpConfiguration = null;
            // 获取IpConfiguration
            for (Field f : filds) {
                if (f.getName().equals("staticIpConfiguration")) {
                    // static ip config
                    mStaticIpConfiguration = f.get(getConfiguration);
                }
            }

            LinkAddress ipAddress = null;
            InetAddress gateway = null;
            ArrayList<InetAddress> dnsServers = null;
            Field[] fields = mStaticIpConfiguration.getClass().getFields();
            for (Field field : fields) {
                if (TextUtils.equals(field.getName(), "ipAddress")) {
                    ipAddress = (LinkAddress) field.get(field.getName());
                } else if (TextUtils.equals(field.getName(), "gateway")) {
                    gateway = (InetAddress) field.get(field.getName());
                } else if (TextUtils.equals(field.getName(), "dnsServers")) {
                    dnsServers = (ArrayList<InetAddress>) field.get(field.getName());
                }
            }
            hashMap = new HashMap<>();
            hashMap.put("ipAddress", ipAddress);
            hashMap.put("gateway", gateway);
            hashMap.put("dnsServers", dnsServers);
            return hashMap;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return hashMap;
    }

    //将子网掩码转换成ip子网掩码形式，比如输入32输出为255.255.255.255
    public String interMask2String(int prefixLength) {
        String netMask = null;
        int inetMask = prefixLength;

        int part = inetMask / 8;
        int remainder = inetMask % 8;
        int sum = 0;

        for (int i = 8; i > 8 - remainder; i--) {
            sum = sum + (int) Math.pow(2, i - 1);
        }

        if (part == 0) {
            netMask = sum + ".0.0.0";
        } else if (part == 1) {
            netMask = "255." + sum + ".0.0";
        } else if (part == 2) {
            netMask = "255.255." + sum + ".0";
        } else if (part == 3) {
            netMask = "255.255.255." + sum;
        } else if (part == 4) {
            netMask = "255.255.255.255";
        }

        return netMask;
    }

    public String setStaticConfig(boolean hasIpSettings, String ip, String netMask, String gateway, String dns1, String dns2) {
        init(mContext);

        if (!TextUtils.isEmpty(ip)) { // not empty
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_IP, ip);
        } else {
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_IP, null);
        }
        if (!TextUtils.isEmpty(gateway)) { // not empty
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_GATEWAY,
                    gateway);
        } else {
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_GATEWAY,
                    null);
        }
        if (!TextUtils.isEmpty(netMask)) { // not empty
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_NETMASK,
                    netMask);
        } else {
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_NETMASK,
                    null);
        }
        if (!TextUtils.isEmpty(dns1)) { // not empty
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_DNS1, dns1);
        } else {
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_DNS1, null);
        }
        if (!TextUtils.isEmpty(dns2)) { // not empty
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_DNS2, dns2);
        } else {
            android.provider.Settings.System.putString(contentResolver, ETHERNET_STATIC_DNS2, null);
        }

        android.provider.Settings.System.putInt(mContext.getContentResolver(),
                ETHERNET_USE_STATIC_IP, 1);

        //获取LinkAddress里面只有一个String类型的构造方法
        Constructor<?> linkAddressConstructor = null;
        try {

            // 获取静态ip配置
            Class<?> staticIpConfig = Class.forName("android.net.StaticIpConfiguration");


            Constructor<?> staticIpConfigConstructor = staticIpConfig.getDeclaredConstructor(staticIpConfig);

            Object staticIpConfigInstance = staticIpConfig.newInstance();

            //获取staticIpConfig中所有的成员变量
            Field[] declaredFields = staticIpConfigInstance.getClass().getDeclaredFields();

            Log.d(TAG, Arrays.asList(declaredFields).toString());


            //存放ipASSignment枚举类参数的集合
            HashMap ipAssignmentMap = new HashMap();

            //存放proxySettings枚举类参数的集合
            HashMap proxySettingsMap = new HashMap();

            Class<?>[] enumClass = ipConfigurationClass.getDeclaredClasses();

            for (Class enumC : enumClass) {

                //获取枚举数组
                Object[] enumConstants = enumC.getEnumConstants();

                if (enumC.getSimpleName().equals("ProxySettings")) {

                    for (Object enu : enumConstants) {

                        //设置代理设置集合 STATIC DHCP UNASSIGNED PAC
                        proxySettingsMap.put(enu.toString(), enu);

                    }

                } else if (enumC.getSimpleName().equals("IpAssignment")) {

                    for (Object enu : enumConstants) {

                        //设置以太网连接模式设置集合 STATIC DHCP UNASSIGNED
                        ipAssignmentMap.put(enu.toString(), enu);

                    }

                }

            }

            Method setIpAssignment = ipConfigurationClass.getDeclaredMethod("setIpAssignment", mIpAssignment.getClass());
            setIpAssignment.setAccessible(true);
            setIpAssignment.invoke(ipConfiguration, hasIpSettings ? ipAssignmentMap.get("STATIC") : ipAssignmentMap.get("DCHP"));


            if (hasIpSettings) {
                for (Field f : declaredFields) {
                    Log.d(TAG, "zhixingle.............." + f.getName());
                    //设置成员变量的值
                    if (f.getName().equals("ipAddress")) {
                        Log.d(TAG, "ip####:" + ip);
                        //实例化 构造方法
                        linkAddressConstructor = LinkAddress.class.getDeclaredConstructor(String.class);
                        LinkAddress linkAddress = (LinkAddress) linkAddressConstructor.newInstance(
                                ip + "/" + maskStr2InetMask(netMask));//192.168.1.1/24--子网掩码长度,24相当于255.255.255.0
                        f.set(staticIpConfigInstance, linkAddress);


                    } else if (f.getName().equals("gateway")) {

                        //设置默认网关

                        if (!TextUtils.isEmpty(gateway)) {
                            try {
                                f.set(staticIpConfigInstance, (Inet4Address) BoardUtil.numericToInetAddress(gateway));
                            } catch (IllegalArgumentException | ClassCastException e) {
//                                return "请填写正确的网关地址！";
                                e.printStackTrace();
                            }
                        }

                    } else if (f.getName().equals("dnsServers")) {

                        //设置DNS
//                        ArrayList<InetAddress> dnsServers = new ArrayList<>();

                        ArrayList dnsServers = (ArrayList) f.get(staticIpConfigInstance);

                        if (!TextUtils.isEmpty(dns1)) {
                            try {
                                dnsServers.add(BoardUtil.numericToInetAddress(dns1));
                            } catch (IllegalArgumentException | ClassCastException e) {
//                                return "请填写正确的DNS地址！";
                                e.printStackTrace();
                            }
                        }

                        if (!TextUtils.isEmpty(dns2)) {
                            try {
                                dnsServers.add(BoardUtil.numericToInetAddress(dns2));
                            } catch (IllegalArgumentException | ClassCastException e) {
//                                return "请填写正确的DNS地址！";
                                e.printStackTrace();
                            }
                        }


                    }
                }

                // 获取ipConfiguration类中带有StaticIpConfiguration参数类型的名叫setStaticIpConfiguration的方法
                Method setStaticIpConfiguration = ipConfigurationClass.getDeclaredMethod("setStaticIpConfiguration", staticIpConfig);
                setStaticIpConfiguration.setAccessible(true);
                //在ipConfiguration对象中使用setStaticIpConfiguration方法,并传入参数
                setStaticIpConfiguration.invoke(ipConfiguration, staticIpConfigInstance);
                Method setConfig = ethernetManagerClass.getDeclaredMethod("setConfiguration", ipConfigurationClass);

                Log.d(TAG, "After Static settings-->" + ipConfiguration); // ok

                // TODO: 2017/8/9 0009 Unknown problem......
                setConfig.invoke(ethernetManager, ipConfiguration);

                return "Static Ip setting ok!";
            }

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }


        return "";
    }

    public void init(Context context) {
        mContext = context;

        try {

            //######################### Instances of EthernetManager and IpConfiguration ################################

            String ETHERNET_SERVICE = (String) Context.class.getField("ETHERNET_SERVICE").get(null);

            ethernetManagerClass = Class.forName("android.net.EthernetManager");

            ipConfigurationClass = Class.forName("android.net.IpConfiguration");

            //获取ethernetManager服务对象
            ethernetManager = context.getSystemService(ETHERNET_SERVICE);

            ipConfiguration = ethernetManagerClass.getDeclaredMethod("getConfiguration").invoke(ethernetManager);


            //######################### Instances of IpAssignment and StaticIpConfiguration ################################

            Field[] filds = ipConfiguration.getClass().getDeclaredFields();

            // 获取IpConfiguration
            for (Field f : filds) {
                if (f.getName().equals("ipAssignment")) { // ip assignment

                    Log.d(TAG, "ipAssignment--->" + f.get(ipConfiguration));
                    mIpAssignment = f.get(ipConfiguration);
                }

                if (f.getName().equals("staticIpConfiguration")) {
                    // static ip config

                    mStaticIpConfiguration = f.get(ipConfiguration);
                }
            }


            //################################# IEthernetManager ######################################


            //获取在EthernetManager中的抽象类mService成员变量
            mService = ethernetManagerClass.getDeclaredField("mService");

            //修改private权限
            mService.setAccessible(true);

            //获取抽象类的实例化对象
            mServiceObject = mService.get(ethernetManager);


            iEthernetManagerClass = Class.forName("android.net.IEthernetManager");

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private InetAddress inetAddress;
    private Field mService;
    private Object mServiceObject;
    private Class<?> iEthernetManagerClass;

    // STATIC DCHP UNASSIGNED
    private Object mIpAssignment;

    //     Describe static Ip configuration
    private Object mStaticIpConfiguration;
    private Object ethernetManager;
    private Object ipConfiguration;
    private Class<?> ipConfigurationClass;
    private Class<?> ethernetManagerClass;

}
